using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

namespace Framework.Library.Core.Utils.Xml
{
    public static class XslUtils
    {
        public static XmlTextReader GetTemplateFromCache(string xslTemplatePath, string templateName)
        {
            string filePath = xslTemplatePath + templateName;
            var sr = new StringReader(File.ReadAllText(filePath));

            return new XmlTextReader(sr);
        }

        public static void TransformNode(XmlNode element, XmlReader xslTemplate)
        {
            XmlReader reader = new XmlNodeReader(element);

            XmlReader transformResultReader = TransformXml(reader, xslTemplate, null);
            element.CreateNavigator().ReplaceSelf(transformResultReader);
        }

        //public static void TransformNavigable(IXPathNavigable navigable, XmlReader xslTemplate)
        //{
        //  XPathNavigator navigator = navigable.CreateNavigator();

        //  XmlReader transformResultReader = TransformXml(navigator, xslTemplate, null);
        //  navigator.ReplaceSelf(transformResultReader);
        //}

        public static XmlReader TransformXml(XmlReader xml, XmlReader xsl)
        {
            XPathNavigator navigator = new XPathDocument(xml).CreateNavigator();
            return TransformXml(navigator, xsl, null);
        }

        public static XmlReader TransformXml(XmlReader xml, XmlReader xsl, XsltArgumentList args, XmlResolver resolver)
        {
            XPathNavigator navigator = new XPathDocument(xml).CreateNavigator();
            return TransformXml(navigator, xsl, args, resolver);
        }

        public static XmlReader TransformXml(XmlReader xml, XmlReader xsl, XsltArgumentList args)
        {
            XPathNavigator navigator = new XPathDocument(xml).CreateNavigator();
            return TransformXml(navigator, xsl, args);
        }

        public static XmlReader TransformXml(XPathNavigator xmlXPathDocument, XmlReader xsl, XsltArgumentList args)
        {
            return TransformXml(xmlXPathDocument, xsl, args, new XmlUrlResolver());
        }

        public static XmlReader TransformXml(XPathNavigator xmlXPathDocument, XmlReader xsl, XsltArgumentList args,
                                             XmlResolver resolver)
        {
            var transform = new XslCompiledTransform();
            transform.Load(xsl, XsltSettings.Default, resolver);
            var ms = new MemoryStream();
            string xml = xmlXPathDocument.OuterXml;
            XmlReader reader = XmlReader.Create(new StringReader(xml));
            transform.Transform(reader, args, ms);
            ms.Seek(0, SeekOrigin.Begin);

            return XmlReader.Create(ms);
        }

        public static XmlReader TransformXml(XmlReader xslTemplate, IDictionary<string, object> parameters)
        {
            return TransformXml(xslTemplate, ToXsltArgumentList(parameters));
        }

        public static XmlReader TransformXml(XmlReader xslTemplate, XsltArgumentList args)
        {
            return TransformXml(XPathUtils.EmptyXPathDocument.CreateNavigator(), xslTemplate, args);
        }

        public static XmlReader TransformXml(string xslTemplatePath, XsltArgumentList args)
        {
            using (XmlReader xmlReader = XmlReader.Create(xslTemplatePath))
            {
                return TransformXml(xmlReader, args);
            }
        }

        public static XsltArgumentList ToXsltArgumentList(IDictionary<string, object> parameters)
        {
            var args = new XsltArgumentList();
            if (parameters != null)
            {
                foreach (var nameValue in parameters)
                {
                    args.AddParam(nameValue.Key, string.Empty, nameValue.Value);
                }
            }

            return args;
        }
    }
}